﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WJP.Utils.Excels
{
    public abstract class AbstractExcelPort : IExcelPort
    {
        #region Reader

        /// <summary>
        /// 读取<see cref="Stream"/>保存为<see cref="DataSet"/>
        /// <para>支持的文件类型为：.xls  .xlsx  .csv</para>
        /// </summary>
        /// <param name="stream">文件的字节流</param>
        /// <returns></returns>
        public abstract DataSet ReaderAsSet(Stream stream);

        /// <summary>
        /// 读取文件保存为<see cref="DataSet"/>
        /// <para>支持的文件类型为：.xls  .xlsx  .csv</para>
        /// </summary>
        /// <param name="filePath">文件的完整路径</param>
        /// <returns></returns>
        public DataSet ReaderAsSet(string filePath)
        {
            var fileInfo = new FileInfo(filePath);
            if (!fileInfo.Exists)
                throw new FileNotFoundException("文件不存在", filePath);
            CheckFileName(fileInfo.Name);

            using (var stream = fileInfo.Open(FileMode.Open, FileAccess.Read))
            {
                return ReaderAsSet(stream);
            }
        }

        /// <summary>
        /// 读取文件保存为<see cref="DataTable"/>
        /// <para>支持的文件类型为：.xls  .xlsx  .csv</para>
        /// </summary>
        /// <param name="filePath">文件的完整路径</param>
        /// <returns></returns>
        public DataTable ReaderAsTable(string filePath)
        {
            var fileInfo = new FileInfo(filePath);
            if (!fileInfo.Exists)
                throw new FileNotFoundException("文件不存在", filePath);
            CheckFileName(fileInfo.Name);

            using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
            {
                return ReaderAsTable(stream);
            }
        }

        /// <summary>
        /// 读取<see cref="Stream"/>保存为<see cref="DataTable"/>
        /// <para>支持的文件类型为：.xls  .xlsx  .csv</para>
        /// </summary>
        /// <param name="stream">文件的字节流</param>
        /// <returns></returns>
        public DataTable ReaderAsTable(Stream stream)
        {
            var set = ReaderAsSet(stream);
            if (set.Tables != null && set.Tables.Count > 0)
                return set.Tables[0];
            return null;
        }

        #endregion Reader

        #region Saver

        /// <summary>
        /// 保存一个DataSet中的多个表到目的Excel文件中，每个Sheet名为对应Table的名字。
        /// </summary>
        /// <param name="dataSet">包含多个表的数据集</param>
        /// <param name="fileName">目的文件地址，如果已经存在，就会覆盖。</param>
        public abstract void SaveToFile(DataSet dataSet, string fileName);

        /// <summary>
        /// 保存table到目的Excel文件中，Sheet名为Table的名字
        /// </summary>
        /// <param name="table">需要存储到excel中的表格数据</param>
        /// <param name="fileName">目的文件地址，如果已经存在，就会覆盖</param>
        public void SaveToFile(DataTable table, string fileName)
        {
            CheckFileName(fileName);
            if (table.DataSet != null)
                table.DataSet.Tables.Remove(table);
            SaveToFile(new DataSet() { Tables = { table } }, fileName);
        }

        #endregion Saver

        /// <summary>
        /// 检查文件名
        /// </summary>
        /// <param name="fileName"></param>
        protected void CheckFileName(string fileName)
        {
            string lower = Path.GetExtension(fileName).ToLower();
            if (lower != ".xlsx" && lower != ".xls" && lower != ".csv")
                throw new NotSupportedException(lower);
        }
    }
}
